//============================================================================
// TITLE: COpcDaServer.h
//
// CONTENTS:
// 
// Implements an OPC Data Access server.
//
// (c) Copyright 2002-2003 The OPC Foundation
// ALL RIGHTS RESERVED.
//
// DISCLAIMER:
//  This code is provided by the OPC Foundation solely to assist in 
//  understanding and use of the appropriate OPC Specification(s) and may be 
//  used as set forth in the License Grant section of the OPC Specification.
//  This code is provided as-is and without warranty or support of any sort
//  and is subject to the Warranty and Liability Disclaimers which appear
//  in the printed OPC Specification.
//
// MODIFICATION LOG:
//
// Date       By    Notes
// ---------- ---   -----
// 2002/09/03 RSA   First release.
// 2002/11/16 RSA   Second release.
// 2003/03/09 RSA   Made autogenerated group names more user friendly.
// 2003/05/13 RSA   Added support for 2.0 only servers.
// 2003/06/25 RSA   Fetch server information for the resource block now.

#ifndef _COpcDaServer_H_
#define _COpcDaServer_H_

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include "COpcDaCache.h"
#include "COpcDaGroup.h"
#include "COpcDaTransaction.h"
#include "COpcThread.h"

//============================================================================
// CLASS:   COpcDaServer
// PURPOSE: A class that implements the IOPCServer interface.
// NOTES:

class COpcDaServer :
    public COpcCommon,
    public COpcCPContainer,
    public IOPCBrowseServerAddressSpace,
    public IOPCItemProperties,
    public IOPCServer,
    public IOPCBrowse,
    public IOPCItemIO,
    public COpcSynchObject
{
    OPC_CLASS_NEW_DELETE()

public:

    //=========================================================================
    // Operators

    // Constructor
    COpcDaServer();

    // Destructor 
    ~COpcDaServer();

    //=========================================================================
    // Public Methods

    // FinalConstruct
    virtual HRESULT FinalConstruct();

    // FinalRelease
    virtual bool FinalRelease();
	
	// CreateGroup
	virtual COpcDaGroup* CreateGroup(COpcDaServer& cServer, const COpcString& cName) { return new COpcDaGroup(cServer, cName); }

	// SetLastUpdateTime
	void SetLastUpdateTime();

	// SetGroupName
	HRESULT SetGroupName(
		const COpcString& cOldName, 
		const COpcString& cNewName);

	// CreateGroup
	HRESULT CreateGroup(
		const COpcString& cName, 
		COpcDaGroup**     ppGroup);

	// CloneGroup
	HRESULT CloneGroup(
		const COpcString& cName, 
		const COpcString& cCloneName, 
		COpcDaGroup**     ppClone);

	// DeleteGroup
	HRESULT DeleteGroup(const COpcString& cName);

    //=========================================================================
    // IOPCServer

    // AddGroup
    STDMETHODIMP AddGroup(
        LPCWSTR    szName,
        BOOL       bActive,
        DWORD      dwRequestedUpdateRate,
        OPCHANDLE  hClientGroup,
        LONG*      pTimeBias,
        FLOAT*     pPercentDeadband,
        DWORD      dwLCID,
        OPCHANDLE* phServerGroup,
        DWORD*     pRevisedUpdateRate,
        REFIID     riid,
        LPUNKNOWN* ppUnk
    );

    // GetErrorString
    STDMETHODIMP GetErrorString( 
        HRESULT dwError,
        LCID    dwLocale,
        LPWSTR* ppString
    );

    // GetGroupByName
    STDMETHODIMP GetGroupByName(
        LPCWSTR    szName,
        REFIID     riid,
        LPUNKNOWN* ppUnk
    );

    // GetStatus
    STDMETHODIMP GetStatus( 
        OPCSERVERSTATUS** ppServerStatus
    );

    // RemoveGroup
    STDMETHODIMP RemoveGroup(
        OPCHANDLE hServerGroup,
        BOOL      bForce
    );

    // CreateGroupEnumerator
    STDMETHODIMP CreateGroupEnumerator(
        OPCENUMSCOPE dwScope, 
        REFIID       riid, 
        LPUNKNOWN*   ppUnk
    );

    //=========================================================================
    // IOPCBrowseServerAddressSpace
    
    // QueryOrganization
    STDMETHODIMP QueryOrganization(OPCNAMESPACETYPE* pNameSpaceType);
    
    // ChangeBrowsePosition
    STDMETHODIMP ChangeBrowsePosition(
        OPCBROWSEDIRECTION dwBrowseDirection,  
        LPCWSTR            szString
    );

    // BrowseOPCItemIDs
    STDMETHODIMP BrowseOPCItemIDs(
        OPCBROWSETYPE   dwBrowseFilterType,
        LPCWSTR         szFilterCriteria,  
        VARTYPE         vtDataTypeFilter,     
        DWORD           dwAccessRightsFilter,
        LPENUMSTRING*   ppIEnumString
    );

    // GetItemID
    STDMETHODIMP GetItemID(
        LPWSTR  wszItemName,
        LPWSTR* pszItemID
    );

    // BrowseAccessPaths
    STDMETHODIMP BrowseAccessPaths(
        LPCWSTR       szItemID,  
        LPENUMSTRING* ppIEnumString
    );

    //=========================================================================
    // IOPCItemProperties

    // QueryAvailableProperties
    STDMETHODIMP QueryAvailableProperties( 
        LPWSTR     szItemID,
        DWORD    * pdwCount,
        DWORD   ** ppPropertyIDs,
        LPWSTR  ** ppDescriptions,
        VARTYPE ** ppvtDataTypes
    );

    // GetItemProperties
    STDMETHODIMP GetItemProperties ( 
        LPWSTR     szItemID,
        DWORD      dwCount,
        DWORD    * pdwPropertyIDs,
        VARIANT ** ppvData,
        HRESULT ** ppErrors
    );

    // LookupItemIDs
    STDMETHODIMP LookupItemIDs( 
        LPWSTR     szItemID,
        DWORD      dwCount,
        DWORD    * pdwPropertyIDs,
        LPWSTR  ** ppszNewItemIDs,
        HRESULT ** ppErrors
    );

    //=========================================================================
    // IOPCBrowse

    // GetProperties
    STDMETHODIMP GetProperties( 
        DWORD		        dwItemCount,
        LPWSTR*             pszItemIDs,
        BOOL		        bReturnPropertyValues,
        DWORD		        dwPropertyCount,
        DWORD*              pdwPropertyIDs,
        OPCITEMPROPERTIES** ppItemProperties 
    );

    // Browse
    STDMETHODIMP Browse(
	    LPWSTR	           szItemName,
	    LPWSTR*	           pszContinuationPoint,
	    DWORD              dwMaxElementsReturned,
		OPCBROWSEFILTER    dwFilter,
	    LPWSTR             szElementNameFilter,
	    LPWSTR             szVendorFilter,
	    BOOL               bReturnAllProperties,
	    BOOL               bReturnPropertyValues,
	    DWORD              dwPropertyCount,
	    DWORD*             pdwPropertyIDs,
	    BOOL*              pbMoreElements,
	    DWORD*	           pdwCount,
	    OPCBROWSEELEMENT** ppBrowseElements
    );
    
    //=========================================================================
    // IOPCItemIO

    // Read
    STDMETHODIMP Read(
        DWORD       dwCount, 
        LPCWSTR   * pszItemIDs,
        DWORD     * pdwMaxAge,
        VARIANT  ** ppvValues,
        WORD     ** ppwQualities,
        FILETIME ** ppftTimeStamps,
        HRESULT  ** ppErrors
    );

    // WriteVQT
    STDMETHODIMP WriteVQT(
        DWORD         dwCount, 
        LPCWSTR    *  pszItemIDs,
        OPCITEMVQT *  pItemVQT,
        HRESULT    ** ppErrors
    );

private:
        
    //==========================================================================
    // Private Members

    COpcString      m_cBrowsePath;
    COpcDaGroupMap  m_cGroups;
    OPCSERVERSTATUS m_cStatus;
	UINT            m_uCounter;
};

#endif // _COpcDaServer_H_